import { isArray } from '@/utils/is.js'
import { constantRoutes, asyncRoutes } from '@/router'

// 判断是否有该权限
const hasPermission = function(route, roles) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  }
  return true
}
// 过滤出对应角色权限的路由列表
export const filterRoutes = function(routes, roles) {
  if (!isArray(routes)) throw new Error('routes 必须为数组')
  const resRoutes = []
  routes.forEach(route => {
    // TODO:若用深拷贝，侧边导航栏会有闪动的bug
    const _route = { ...route }
    if (hasPermission(_route, roles)) {
      if (_route.children) {
        _route.children = filterRoutes(_route.children, roles)
      }
      resRoutes.push(_route)
    }
  })
  return resRoutes
}

const state = {
  addRoutes: [], // 角色权限路由列表
  menus: [], // 侧边导航菜单
  keepAliveComponents: [] // 需要缓存组件名称
}

const mutations = {
  // 设置路由
  setRoutes: (state, _routes) => {
    state.addRoutes = _routes
    state.menus = constantRoutes.concat(_routes)
  },
  // 设置缓存组件名称
  setKeepAliveComponents: (state, componentNames) => {
    state.keepAliveComponents = componentNames
  },
  // 删除缓存组件名称某项
  removeKeepAliveComponents: (state, componentName) => {
    const index = state.keepAliveComponents.find(name => name === componentName)
    if (index) {
      state.keepAliveComponents.splice(index, 1)
    }
  },
  // 清空所有缓存组件名称
  clearKeepAliveComponents: (state) => {
    state.keepAliveComponents = []
  }
}

const actions = {
  // 动态获取菜单
  generateRoutes: async({ commit }, roles) => {
    return new Promise(resolve => {
      let accessedRoutes = []
      // 超级管理员
      if (roles.includes(1)) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterRoutes(asyncRoutes, roles)
      }
      commit('setRoutes', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

const getters = {
  addRoutes: (state) => state.addRoutes,
  menus: (state) => state.menus,
  keepAliveComponents: (state) => state.keepAliveComponents
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
